iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
自我挑戰組

JavaScript101與人生幹話系列 第 29

JavaScript101與人生幹話 - 屬性的特徵與Getter/Setter

  • 分享至 

  • xImage
  •  

屬性的特徵與Getter/Setter

1-1屬性特徵是什麼?

有四點
1.value,也就是物件屬性的值。
2.writable,屬性的值能不能被寫入。
3.configurable,屬性能不能被刪除。
4.enumerable,屬性能不能被列舉。

屬性的特徵預設都是ture,value沒有特別設定的話就是最後所賦值。

1-2如何更改屬性的特徵?

使用Object.defineProperty()
Object.definePorperty(物件,'屬性',參數)
使用的範例如下

const obj = {
  a:'a',
  b:'b',
  c:'c',
  b:'b'
}
// 修改屬性特徵
//Object.definePorperty(物件,'屬性',參數)
//參數{value:,writable:boolean,configable:boolean,enumerable:boolean}
// 參數可以只寫要修改就好,下面是因為展示與練習需要才寫全

// 修改值
Object.defineProperty(obj, 'a',{
  value:1,
  writable:true,
  configurable:true,
  enumerable:true,
})
console.log('obj屬性a的值被修改為',obj.a) // 1

// writable:false 屬性的值是否能被修改

Object.defineProperty(obj, 'b',{
  writable:false
})
obj.b = 2
console.log('obj屬性b的值為',obj.b) // "b" 

// configurable:false 屬性的值是否能被刪除

Object.defineProperty(obj, 'c', {
  configurable:false
})

delete obj.c
console.log(obj.c) // "c"

// enumerable 屬性是否可被列舉

Object.defineProperty(obj, 'd', {
  enumerable:false
})

const objProperty = Object.keys(obj)
const objValue = Object.values(obj)
console.log(objProperty) // ["a", "b", "c"]  注意沒有出現d這個屬性
console.log(objValue) // ["1", "b", "c"]  注意沒有出現d的的值

1-3如何一次更改多個屬性特徵?

使用Object.definePropertys(物件,{"屬性":{參數}})

const obj2 = {
  A:'A',
  B:'B',
  C:'C'
}
Object.defineProperties(obj2, {'A':{value:'123',
                                  configurable: false},
                             'B':{writable: false,
                                  enumerable: false},
                             'C':{value:'abc',
                                  writable: false,
                                  configurable:false,
                                  enumerable: false}})
delete obj2.A  
console.log('obj2屬性a的值:',obj2.A) // "123" 且無法被刪除

obj2.B = 123
console.log(obj2.B) // obj2屬性B的值無法被寫入

obj2.C = 'STRING'
delete obj2.C
console.log(obj2.C) // "abc"
console.log(Object.keys(obj2)) // ["A"]  B 與 c無法被列舉 

1-4巢狀的物件屬性不會被影響

直接看範例

const obj3 = {
  a:{
    A:'123'
  }
}
Object.defineProperty(obj3, 'a', {writable:false})
obj3.a = 123
console.log(obj3.a) //{A:'123'}  
obj3.a.A = 'STRING'
console.log(obj3.a.A) // 'STRING' 不受writable:false的影響可以寫入

屬性的特性修改範例

2-1物件擴充的修改與調整

這裡可以看做是物件的特徵,與屬性相同可以透過與法設定物件的特性,讓物件能不能寫入或刪除新的屬性。

2-2preventExtensions防止擴充

就是不讓物件新增新的屬性。
物件的屬性值可以修改。
物件的屬性可以刪除。
物件屬性特徵可以調整。
巢狀屬性的值可修改。
範例如下

// Object.preventExtensions(物件)
const obj = {
  a:'a',
  b:'b',
  c:{}
}
Object.preventExtensions(obj)
console.log('obj是否可擴充', Object.isExtensible(obj))
console.log('obj a的屬性特膯', Object.getOwnPropertyDescriptor(obj, 'a')) 
//{
//  value:"a",
//  writable:true,
//  configurable:true,
//  enumerable:true,
//}
obj.d = 'd'
console.log(obj.d) // undefind
Object.defineProperty(obj, 'a', {value:1,writable:false})
obj.a = 123
console.log(obj.a) // 1
obj.b = 2 
console.log(obj.b) / 2
obj.c.a = 789
console.log(obj.c.a) // 789

2-3 seal

就是不讓物件新增新的屬性。
物件的屬性值可以修改。
物件的屬性不可刪除。
物件屬性特徵不可以調整。
巢狀屬性的值可修改。
範例如下

const obj2 = {
  a:'a',
  b:'b',
  c:{}
}
Object.seal(obj2)
console.log('obj2是否可擴充', Object.isExtensible(obj2))
console.log('obj2是否封裝', Object.isSealed(obj2))
console.log('obj2 a的屬性特徵', Object.getOwnPropertyDescriptor(obj2, 'a')) 
//{
//  value:"a",
//  writable:true,
//  configurable:false,
//  enumerable:true,
//}
obj2.d = 'd'
console.log(obj2.d) // undefind
// Object.defineProperty(obj2, 'a', {value:1,writable:false}) 會報錯不可執行
obj2.a = 123
console.log(obj2.a) // 1
obj2.b = 2 
console.log(obj2.b) / 2
obj2.c.a = 789
console.log(obj2.c.a) // 789
delete obj2.b
console.log(obj2.b) // 2

2-4 frezzez

就是不讓物件新增新的屬性。
物件的屬性值不可修改。
物件的屬性不可刪除。
物件屬性特徵不可以調整。
巢狀屬性的值可修改。
範例如下

const obj3 = {
  a:'a',
  b:'b',
  c:{}
}
Object.freeze(obj3)
console.log('obj3是否可擴充', Object.isExtensible(obj3))
console.log('obj3是否封裝', Object.isSealed(obj3))
console.log('obj3是否凍結', Object.isFrozen(obj3))
console.log('obj3 a的屬性特徵', Object.getOwnPropertyDescriptor(obj3, 'a')) 
//{
//  value:"a",
//  writable:false,
//  configurable:false,
//  enumerable:true,
//}
obj3.d = 'd'
console.log(obj2.d) // undefind
// Object.defineProperty(obj3, 'a', {value:1,writable:true}) 會報錯不可執行
obj3.a = 123
console.log(obj3.a) // "a"
obj3.b = 2 
console.log(obj3.b) // "b"
obj3.c.a = 789
console.log(obj3.c.a) // 789
delete obj3.b
console.log(obj3.b) // "b"

2-5 對照表

preventExtensions seal frezzez
物件新增新的屬性
物件的屬性值修改
物件的屬性刪除
物件屬性特徵調整
巢狀屬性的值可修改

3 屬性列舉與原型的關係

4 Getter 與 Setter,賦值運算不使用函式

get取得值的方法
set寫入值的方法

4-1 實際使用的範例

const obj = {
  money:100,
  set save(num){
    this.money = this.money + num
  },
  // get可以與set同名,因為get是取得數值,所以不用傳入參數。
  get save(){
    return this.money / 2
}
}
// 用get取得數值
console.log(obj.save) //50

// 其中的"save":"..." 如果點開的話會直接出現最後的結果 
console.log(obj) 
//{
//money:100
//save:"..."
//}

// 要用賦值的方式寫入
obj.save = 500

console.log(obj.money) //600

console.log(obj.save) // 300

下圖為save點開前

下圖為save點開後

4-2 用Object.defineProperty() 加入get 與 set

const obj2 = {
  money:100
}

Object.defineProperty(obj2, 'save',{
  // enumerable:true,
  // configurable:true,
  get:function(){
    return this.money
  },
  set:function(num){
    this.money = this.money + num
  }
})

obj2.save = 200
console.log(obj2.money) // 300
console.log('save',obj2.save) // 300
console.log(Object.getOwnPropertyDescriptor(obj2, 'save')) 
// 可以看到eumerable(可列舉)與configurable(可刪除)都是false, 
// 可以在上方加入enumerable:true與 configurable:true

4-3 使用Object.defineProperty修改Array.prototype

Object.defineProperty(Array.prototype, 'lastIndex',{
  get:function(){
    return this[this.length - 1]
  }
})
const arr = [1, 2, 3, 4] 

console.log(arr.lastIndex) // 4
// 補充使用 Array.prototype的方法
Array.prototype.last = function(){
  return this[this.length - 1]
}
console.log(arr.last()) // 4

生人幹話 - 努力就一定有回報嗎?

在順利完成了真的風險評估報告的第一版差不多是2021年初,每次到年初的時候都有人員約談,簡單的來說就是你去年做了什麼,今年打算做什麼,以及能提出工作績效的證據,原則上我是想用爬蟲醫材的資料並且自動分析,不用在手動上網找,然後複製貼上到excell上分析,被主管強力的建議甩鍋當講師,還有繼續維護文件,我有要求加薪,但是就被主管回了一句幹話「我認為沒有人是不可取代的,blabla…」,這個時候我已經不想去聽那些幹話了,總之就是不給加,到了過農曆年,經過大主管口述,年終獎金至少1-2個月,依照考績發給,這個時候我認為雖然沒爭取加薪成功,但是我應該至少拿到1個月的年終獎金,畢竟在主管講完所謂的沒有人是不可取代的幹話之後還是在我的考績上打了優。


上一篇
JavaScript101與人生幹話- 繼承與原型鍊
下一篇
JavaScript101與人生幹話 - 我所不知道的樣板字面值
系列文
JavaScript101與人生幹話30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言